+2005-09-08 Øyvind Kolås <pippin@gimp.org>
+
+ Made simple fishes work in the core.
+
+ * babl/babl-classes.h: reduced number of conversion classes.
+ removed unused from and to members in struct.
+ * babl/babl-conversion.c: (conversion_new), (babl_conversion_new),
+ (babl_conversion_linear_process), (babl_conversion_plane_process),
+ (babl_conversion_planar_process), (babl_conversion_process):
+ * babl/babl-component.c: (each_babl_component_destroy),
+ (component_new): removed unused from and to members.
+ * babl/babl-fish.c: (babl_conversion_find2),
+ (babl_conversion_find), (babl_fish_reference), (babl_fish_simple),
+ (babl_fish), (convert_to_double), (convert_from_double),
+ (babl_fish_reference_process): use fast path if found directly in a
+ simple fishes.
+ * babl/babl-format.c: (babl_format_new):
+ * babl/babl-internal.c: (babl_process):
+ * babl/babl-internal.h:
+ * babl/babl-introspect.c: (each_introspect):
+ * babl/babl-model.c: (babl_model_new):
+ * babl/babl-core.c: (babl_core_init): s/linear/plane/
+
2005-09-08 Øyvind Kolås <pippin@gimp.org>
* AUTHORS: Added Micahel Schumacher, and email addresses.
/* Type and Format */
typedef long (*BablFuncLinear) (void *src,
+ void *dst,
+ long n);
+
+/* Signature of functions registered for reference type
+ * conversions,
+ */
+typedef long (*BablFuncPlane) (void *src,
void *dst,
int src_pitch,
int dst_pitch,
long n);
-/* TypePlanar, ModelPlanar and FormatPlanar */
+/* TypePlanar,ModelPlanar and FormatPlanar */
typedef long (*BablFuncPlanar) (int src_bands,
void *src[],
int src_pitch[],
int dst_pitch[],
long n);
+#if 0
typedef long (*BablFuncPlanarBit) (int src_bands,
void *src[],
int src_bit[],
int dst_pitch[],
int dst_bit_pitch[],
long n);
+#endif
/* magic number used at the start of all babl objects, used to do
* differentiation in polymorphic functions. (as well as manual
BABL_FORMAT,
BABL_CONVERSION,
- BABL_CONVERSION_TYPE,
- BABL_CONVERSION_TYPE_PLANAR,
- BABL_CONVERSION_MODEL_PLANAR,
- BABL_CONVERSION_FORMAT,
- BABL_CONVERSION_FORMAT_PLANAR,
+ BABL_CONVERSION_LINEAR,
+ BABL_CONVERSION_PLANE,
+ BABL_CONVERSION_PLANAR,
BABL_FISH,
BABL_FISH_REFERENCE,
+ BABL_FISH_SIMPLE,
BABL_IMAGE,
BABL_EXTENSION,
union
{
BablFuncLinear linear;
+ BablFuncPlane plane;
BablFuncPlanar planar;
- BablFuncPlanarBit planar_bit;
} function;
int processings;
long pixels;
} BablConversion;
-typedef struct {
- BablConversion conversion;
- BablConversion *from_double;
- BablConversion *to_double;
-} BablConversionType;
-
-typedef struct
-{
- BablConversion conversion;
-} BablConversionTypePlanar;
-
-typedef struct
-{
- BablConversion conversion;
-} BablConversionModelPlanar;
-
-typedef struct
-{
- BablConversion conversion;
-} BablConversionFormat;
-
-typedef struct
-{
- BablConversion conversion;
-} BablConversionFormatPlanar;
typedef struct
{
typedef struct
{
BablInstance instance;
- BablConversion **from; /*< NULL terminated list of conversions from class */
- BablConversion **to; /*< NULL terminated list of conversions to class */
int luma;
int chroma;
int alpha;
BablFish fish;
} BablFishReference;
+/* BablFishSimple is the simplest type of fish, wrapping a single
+ * conversion function
+ */
+typedef struct
+{
+ BablFish fish;
+ BablConversion *conversion;
+} BablFishSimple;
+
typedef struct
{
BablInstance instance; /* path to .so / .dll is stored in instance name */
BablImage image;
BablFish fish;
BablFishReference reference_fish;
+ BablFishSimple fish_simple;
BablExtension extension;
} Babl;
each_babl_component_destroy (Babl *babl,
void *data)
{
- babl_free (babl->component.from);
- babl_free (babl->component.to);
babl_free (babl);
return 0; /* continue iterating */
}
babl->component.luma = luma;
babl->component.chroma = chroma;
babl->component.alpha = alpha;
- babl->component.from = NULL;
- babl->component.to = NULL;
return babl;
}
int time_cost,
int loss,
BablFuncLinear linear,
- BablFuncPlanar planar,
- BablFuncPlanarBit planar_bit)
+ BablFuncPlane plane,
+ BablFuncPlanar planar)
{
Babl *babl = NULL;
- /* destination is of same type as source */
+ babl_assert (source->class_type ==
+ destination->class_type);
+
+ if (linear)
+ {
+ babl = babl_malloc (sizeof (BablConversion));
+ babl->class_type = BABL_CONVERSION_LINEAR;
+ babl->conversion.function.linear = linear;
+ }
+ else if (plane)
+ {
+ babl = babl_malloc (sizeof (BablConversion));
+ babl->class_type = BABL_CONVERSION_PLANE;
+ babl->conversion.function.plane = plane;
+ }
+ else if (planar)
+ {
+ babl = babl_malloc (sizeof (BablConversion));
+ babl->class_type = BABL_CONVERSION_PLANAR;
+ babl->conversion.function.planar = planar;
+ }
switch (source->class_type)
{
case BABL_TYPE:
- if (linear)
- {
- babl = babl_malloc (sizeof (BablConversionType));
- babl->class_type = BABL_CONVERSION_TYPE;
- babl->conversion.function.linear = linear;
- }
- else if (planar)
- {
- babl = babl_malloc (sizeof (BablConversionTypePlanar));
- babl->class_type = BABL_CONVERSION_TYPE_PLANAR;
- babl->conversion.function.planar = planar;
- }
- else if (planar_bit)
- {
- babl_log ("planar_bit support not implemented yet");
- }
break;
case BABL_MODEL:
if (linear)
{
- babl_log ("linear support for model conversion not supported");
- }
- else if (planar)
- {
- babl = babl_malloc (sizeof (BablConversionModelPlanar));
- babl->class_type = BABL_CONVERSION_MODEL_PLANAR;
- babl->conversion.function.planar = planar;
+ babl_fatal ("linear support for %s not supported",
+ babl_class_name (source->class_type));
}
- else if (planar_bit)
+ else if (plane)
{
- babl_log ("planar_bit support for model conversion not supported");
+ babl_fatal ("plane support for %s not supported",
+ babl_class_name (source->class_type));
}
break;
case BABL_FORMAT:
- if (linear)
- {
- babl = babl_malloc (sizeof (BablConversionFormat));
- babl->class_type = BABL_CONVERSION_FORMAT;
- babl->conversion.function.linear = linear;
- }
- else if (planar)
- {
- babl = babl_malloc (sizeof (BablConversionFormatPlanar));
- babl->class_type = BABL_CONVERSION_FORMAT_PLANAR;
- babl->conversion.function.planar = planar;
- }
- else if (planar_bit)
- {
- babl_log ("planar_bit support for pixelformat conversion not supported");
- }
break;
default:
- babl_log ("%s unexpected", babl_class_name (babl->class_type));
+ babl_fatal ("%s unexpected", babl_class_name (babl->class_type));
break;
}
- if (!babl)
- {
- babl_log ("args=(name='%s', ...): creation failed", name);
- return NULL;
- }
babl->instance.id = id;
babl->instance.name = babl_strdup (name);
int time_cost = 0;
int loss = 0;
BablFuncLinear linear = NULL;
+ BablFuncPlane plane = NULL;
BablFuncPlanar planar = NULL;
- BablFuncPlanarBit planar_bit = NULL;
int got_func = 0;
const char *arg = first_arg;
{
if (got_func++)
{
- babl_log ("already got a conversion func, registration of multiple might be possible later\n");
+ babl_fatal ("already got a conversion func\n");
}
linear = va_arg (varg, BablFuncLinear);
}
- else if (!strcmp (arg, "planar"))
+ else if (!strcmp (arg, "plane"))
{
if (got_func++)
{
- babl_log ("already got a conversion func, registration of multiple might be possible later\n");
+ babl_fatal ("already got a conversion func\n");
}
- planar = va_arg (varg, BablFuncPlanar);
+ plane = va_arg (varg, BablFuncPlane);
}
- else if (!strcmp (arg, "planar-bit"))
+ else if (!strcmp (arg, "planar"))
{
if (got_func++)
{
- babl_log ("already got a conversion func, registration of multiple might be possible later\n");
+ babl_fatal ("already got a conversion func\n");
}
- planar_bit = va_arg (varg, BablFuncPlanarBit);
+ planar = va_arg (varg, BablFuncPlanar);
}
else if (!strcmp (arg, "time-cost"))
assert (source);
assert (destination);
- babl = conversion_new (create_name (source, destination), id, source, destination, time_cost, loss, linear,
- planar, planar_bit);
+ babl = conversion_new (create_name (source, destination),
+ id, source, destination, time_cost, loss, linear, plane, planar);
{
Babl *ret = babl_db_insert (db, babl);
babl_conversion_linear_process (BablConversion *conversion,
void *source,
void *destination,
- int src_pitch,
- int dst_pitch,
long n)
{
- conversion->function.linear (source, destination, src_pitch, dst_pitch, n);
- return n;
+ return conversion->function.linear (source, destination, n);
+}
+
+static long
+babl_conversion_plane_process (BablConversion *conversion,
+ void *source,
+ void *destination,
+ int src_pitch,
+ int dst_pitch,
+ long n)
+{
+ return conversion->function.plane (source, destination,
+ src_pitch, dst_pitch,
+ n);
}
static long
memcpy (src_data, source->data, sizeof (void*) * source->components);
memcpy (dst_data, destination->data, sizeof (void*) * destination->components);
- conversion->function.planar (source->components,
- src_data,
- source->pitch,
- destination->components,
- dst_data,
- destination->pitch,
- n);
- return n;
+ return conversion->function.planar (source->components,
+ src_data,
+ source->pitch,
+ destination->components,
+ dst_data,
+ destination->pitch,
+ n);
}
long
switch (BABL(conversion)->class_type)
{
- case BABL_CONVERSION_TYPE:
+ case BABL_CONVERSION_PLANE:
{
void *src_data = NULL;
void *dst_data = NULL;
src_data = img->data[0];
src_pitch = img->pitch[0];
}
- if (!src_data)
- src_data=source;
- if (!src_pitch)
- src_pitch=BABL(conversion->source)->type.bits/8;
-
-
if (BABL_IS_BABL(destination))
{
- BablImage *img;
+ BablImage *img = (BablImage*)destination;
- img = (BablImage*)destination;
dst_data = img->data[0];
dst_pitch = img->pitch[0];
}
+
+ if (!src_data)
+ src_data=source;
+ if (!src_pitch)
+ src_pitch=BABL(conversion->source)->type.bits/8;
if (!dst_data)
dst_data=destination;
if (!dst_pitch)
dst_pitch=BABL(conversion->destination)->type.bits/8;
- babl_conversion_linear_process (conversion,
- src_data, dst_data,
- src_pitch, dst_pitch,
- n);
+ babl_conversion_plane_process (conversion,
+ src_data, dst_data,
+ src_pitch, dst_pitch,
+ n);
}
break;
- case BABL_CONVERSION_MODEL_PLANAR:
+ case BABL_CONVERSION_PLANAR:
babl_assert (BABL_IS_BABL (source));
babl_assert (BABL_IS_BABL (destination));
(BablImage*) destination,
n);
break;
+ case BABL_CONVERSION_LINEAR:
+ babl_assert (!BABL_IS_BABL (source));
+ babl_assert (!BABL_IS_BABL (destination));
+
+ babl_conversion_linear_process (conversion,
+ source,
+ destination,
+ n);
+ break;
+
default:
babl_log ("args=(%s, %p, %p, %li) unhandled conversion type: %s",
conversion->instance.name, source, destination, n,
babl_conversion_new (
babl_type_id (BABL_DOUBLE),
babl_type_id (BABL_DOUBLE),
- "linear", convert_double_double,
+ "plane", convert_double_double,
NULL
);
BablConversion *result;
} SearchData;
-Babl *babl_conversion_find (void *source,
+Babl *babl_conversion_find2 (void *source,
void *destination)
{
int i=0;
Babl **conversion;
conversion = (void*)BABL(source)->type.from;
- while (conversion[i])
+ while (conversion && conversion[i])
{
if (conversion[i]->conversion.destination == destination)
return (Babl*)conversion[i];
}
+Babl *babl_conversion_find (void *source,
+ void *destination)
+{
+ int i=0;
+ Babl **conversion;
+
+ conversion = (void*)BABL(source)->type.from;
+ while (conversion && conversion[i])
+ {
+ if (conversion[i]->conversion.destination == destination)
+ return (Babl*)conversion[i];
+ i++;
+ }
+ return NULL;
+}
+
+
+
Babl *
-babl_fish_reference_new (Babl *source,
- Babl *destination)
+babl_fish_reference (Babl *source,
+ Babl *destination)
{
Babl *babl = NULL;
char *name = create_name (source, destination, 1);
}
}
+Babl *
+babl_fish_simple (BablConversion *conversion)
+{
+ Babl *babl = NULL;
+ char *name;
+
+ babl_assert (BABL_IS_BABL (conversion));
+
+ name = create_name (BABL(conversion->source),
+ BABL(conversion->destination),
+ 0);
+
+ babl = babl_malloc (sizeof (BablFishSimple) +
+ strlen (name) + 1);
+ babl->class_type = BABL_FISH_SIMPLE;
+ babl->instance.id = 0;
+ babl->instance.name = ((void *)babl) + sizeof(BablFishSimple);
+ strcpy (babl->instance.name, name);
+ babl->fish.source = (union Babl*)conversion->source;
+ babl->fish.destination = (union Babl*)conversion->destination;
+
+ babl->fish.processings = 0;
+ babl->fish.pixels = 0;
+ babl->fish_simple.conversion = conversion;
+
+ {
+ Babl *ret = babl_db_insert (db, babl);
+ if (ret!=babl)
+ babl_free (babl);
+ return ret;
+ }
+}
+
Babl *
babl_fish (void *source,
void *destination)
babl_log ("args=(%p, %p) destination format invalid", source, destination);
return NULL;
}
-
- return babl_fish_reference_new (source_format, destination_format);
+
+
+ {
+ Babl *shortcut_conversion = babl_conversion_find (source_format, destination_format);
+
+ if (shortcut_conversion)
+ {
+ return babl_fish_simple (&(shortcut_conversion->conversion));
+ }
+ }
+ return babl_fish_reference (source_format, destination_format);
}
}
babl_process (
- babl_conversion_find (src_img->type[0], dst_img->type[0]),
+ babl_conversion_find2 (src_img->type[0], dst_img->type[0]),
src_img, dst_img,
n);
src_img->data[0] += src_img->type[0]->bits/8;
}
babl_process (
- babl_conversion_find (src_img->type[0], dst_img->type[0]),
+ babl_conversion_find2 (src_img->type[0], dst_img->type[0]),
src_img, dst_img,
n);
dst_img->data[0] += dst_img->type[0]->bits/8;
);
babl_process (
- babl_conversion_find (
+ babl_conversion_find2 (
BABL(babl->fish.source)->format.model,
babl_model_id (BABL_RGBA)
),
n);
babl_process (
- babl_conversion_find (
+ babl_conversion_find2 (
babl_model_id (BABL_RGBA),
BABL(babl->fish.destination)->format.model
),
case BABL_COMPONENT:
if (!model)
{
- babl_log ("no model specified before component %s",
- babl->instance.name);
+ babl_fatal ("no model specified before component %s",
+ babl->instance.name);
}
component [components] = (BablComponent*) babl;
type [components] = current_type;
if (components>=BABL_MAX_COMPONENTS)
{
- babl_log ("maximum number of components (%i) exceeded for %s",
- BABL_MAX_COMPONENTS, name);
+ babl_fatal ("maximum number of components (%i) exceeded for %s",
+ BABL_MAX_COMPONENTS, name);
}
break;
case BABL_SAMPLING:
case BABL_INSTANCE:
case BABL_FORMAT:
case BABL_CONVERSION:
- case BABL_CONVERSION_TYPE:
- case BABL_CONVERSION_TYPE_PLANAR:
- case BABL_CONVERSION_MODEL_PLANAR:
- case BABL_CONVERSION_FORMAT:
- case BABL_CONVERSION_FORMAT_PLANAR:
+ case BABL_CONVERSION_LINEAR:
+ case BABL_CONVERSION_PLANE:
+ case BABL_CONVERSION_PLANAR:
case BABL_FISH:
case BABL_FISH_REFERENCE:
case BABL_IMAGE:
"BablModel",
"BablFormat",
"BablConversion",
- "BablConversionType",
- "BablConversionTypePlanar",
- "BablConversionModelPlanar",
- "BablConversionFormat",
- "BablConversionFormatPlanar",
+ "BablConversionLinear",
+ "BablConversionPlane",
+ "BablConversionPlanar",
"BablFish",
"BablFishReference",
+ "BablFishSimple",
"BablImage",
"BablExtenstion",
"BablSky"
/* matches all conversion classes */
if (babl->class_type >= BABL_CONVERSION &&
- babl->class_type <= BABL_CONVERSION_FORMAT_PLANAR)
+ babl->class_type <= BABL_CONVERSION_PLANAR)
return babl_conversion_process (babl, source, destination, n);
if (babl->class_type == BABL_FISH)
{
BablImage *source_image = NULL;
BablImage *destination_image = NULL;
+ long ret=0;
if (BABL_IS_BABL (source))
source_image = source;
destination_image = (BablImage*) babl_image_from_linear (
destination, (Babl*)babl->fish.destination);
- babl_fish_reference_process (babl, source, destination, n);
+ ret = babl_fish_reference_process (babl, source, destination, n);
babl_free (source_image);
babl_free (destination_image);
- return 0;
+ return ret;
+ }
+
+ if (babl->class_type == BABL_FISH_SIMPLE)
+ {
+ long ret=0;
+ BablImage *source_image = NULL;
+ BablImage *destination_image = NULL;
+
+ if (BABL_IS_BABL (source))
+ source_image = source;
+ if (!source_image)
+ source_image = (BablImage*) babl_image_from_linear (
+ source, (Babl*)babl->fish.source);
+ if (BABL_IS_BABL (destination))
+ destination_image = destination;
+ if (!destination_image)
+ destination_image = (BablImage*) babl_image_from_linear (
+ destination, (Babl*)babl->fish.destination);
+
+ if (BABL(babl->fish_simple.conversion)->class_type==BABL_CONVERSION_LINEAR)
+ {
+ ret = babl_conversion_process (BABL(babl->fish_simple.conversion),
+ source, destination, n);
+ }
+ else
+ {
+ ret = babl_conversion_process (BABL(babl->fish_simple.conversion),
+ source_image, destination_image, n);
+ }
+
+ babl_free (source_image);
+ babl_free (destination_image);
+
+ return ret;
}
babl_log ("eek");
BablImage *source,
BablImage *destination,
long n);
+Babl * babl_fish_reference (Babl *source,
+ Babl *destination);
+Babl * babl_fish_simple (BablConversion *conversion);
Babl * babl_image_from_linear (void *buffer,
Babl *format);
Babl * babl_image_double_from_image (Babl *source);
item_conversions_introspect (babl);
break;
case BABL_COMPONENT:
- item_conversions_introspect (babl);
break;
case BABL_MODEL:
model_introspect (babl);
item_conversions_introspect (babl);
break;
case BABL_CONVERSION:
- case BABL_CONVERSION_TYPE:
- case BABL_CONVERSION_TYPE_PLANAR:
- case BABL_CONVERSION_MODEL_PLANAR:
- case BABL_CONVERSION_FORMAT:
- case BABL_CONVERSION_FORMAT_PLANAR:
+ case BABL_CONVERSION_PLANE:
+ case BABL_CONVERSION_PLANAR:
+ case BABL_CONVERSION_LINEAR:
conversion_introspect (babl);
break;
case BABL_FISH:
- fish_introspect (babl);
- break;
case BABL_FISH_REFERENCE:
+ case BABL_FISH_SIMPLE:
fish_introspect (babl);
break;
default:
case BABL_CONVERSION:
- case BABL_CONVERSION_TYPE:
- case BABL_CONVERSION_TYPE_PLANAR:
- case BABL_CONVERSION_MODEL_PLANAR:
- case BABL_CONVERSION_FORMAT:
- case BABL_CONVERSION_FORMAT_PLANAR:
+ case BABL_CONVERSION_LINEAR:
+ case BABL_CONVERSION_PLANE:
+ case BABL_CONVERSION_PLANAR:
case BABL_FISH:
case BABL_FISH_REFERENCE:
case BABL_IMAGE: